package com.suse.lhw.hms.authserver.config;

import com.alibaba.fastjson.JSON;
import com.suse.lhw.hms.authserver.tools.RedisTokenStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * import javax.sql.DataSource;
 *
 * @ProjectName: health_manage_system
 * @Package: com.suse.lhw.hms.authserver.config
 * @ClassName: AuthorizationServerConfiguration
 * @Description: java类作用描述
 * @Author: 李鸿炜
 * @CreateDate: 2020/3/28 17:55
 * @UpdateUser: 更新者
 * @UpdateDate: 2020/3/28 17:55
 * @UpdateRemark: 更新说明
 * @Version: 1.0
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
    // 资源ID
    private static final String SOURCE_ID = "order";
    private static final int ACCESS_TOKEN_TIMER = 60 * 60 * 24;
    private static final int REFRESH_TOKEN_TIMER = 60 * 60 * 24 * 30;

    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        /**
         * @Author:Hongwei Li
         * @Description:security 数据源配置
         * @Date:15:30 2020/3/28
         * @Return:javax.sql.DataSource
         **/
        return DataSourceBuilder.create().build();
    }


//    @Override
//    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
//        /**
//         * @Author:Hongwei Li
//         * @Description:
//         * @Date:15:27 2020/4/9
//         * @Param:[clients]
//         * @Return:void
//        **/
//        clients.inMemory().withClient("myapp").resourceIds(SOURCE_ID).authorizedGrantTypes("password", "refresh_token")
//                .scopes("all").authorities("ADMIN").secret("lxapp").accessTokenValiditySeconds(ACCESS_TOKEN_TIMER)
//                .refreshTokenValiditySeconds(REFRESH_TOKEN_TIMER);
//    }
//
//    @Override
//    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {/**
//     * @Author:Hongwei Li
//     * @Description:
//     * @Date:15:28 2020/4/9
//     * @Param:[endpoints]
//     * @Return:void
//    **/
//
//        endpoints.accessTokenConverter(accessTokenConverter());
//        endpoints.tokenStore(tokenStore()).authenticationManager(authenticationManager);
//    }
//    // JWT
//    @Bean
//    public JwtAccessTokenConverter accessTokenConverter() {
//        /**
//         * @Author:Hongwei Li
//         * @Description:
//         * @Date:15:27 2020/4/9
//         * @Param:[]
//         * @Return:org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter
//        **/
//        JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter() {
//            /***
//             * 重写增强token方法,用于自定义一些token总需要封装的信息
//             */
//            @Override
//            public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
//                System.out.println(" public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {\n" +
//                        "      ");
//                String userName = authentication.getUserAuthentication().getName();
//                // 得到用户名，去处理数据库可以拿到当前用户的信息和角色信息（需要传递到服务中用到的信息）
//                final Map<String, Object> additionalInformation = new HashMap<>();
//                // Map假装用户实体
//                Map<String, String> userinfo = new HashMap<>();
//                userinfo.put("id", "1");
//                userinfo.put("username", "LiaoXiang");
//                userinfo.put("qqnum", "438944209");
//                userinfo.put("userFlag", "1");
//                additionalInformation.put("userinfo", JSON.toJSONString(userinfo));
//                ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInformation);
//                OAuth2AccessToken enhancedToken = super.enhance(accessToken, authentication);
//                return enhancedToken;
//            }
//        };
//        // 测试用,资源服务使用相同的字符达到一个对称加密的效果,生产时候使用RSA非对称加密方式
//        accessTokenConverter.setSigningKey("SigningKey");
//        return accessTokenConverter;
//    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        // 允许表单认证
        oauthServer.allowFormAuthenticationForClients();
    }

    @Bean
    public TokenStore tokenStore() {
        return new RedisTokenStore(redisConnectionFactory);
    }

//    @Override
//    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
//        endpoints
//                .authenticationManager(authenticationManager)
//                .tokenStore(tokenStore());
//    }
//


    public ClientDetailsService jdbcClientDeatails() {
        return new JdbcClientDetailsService(dataSource());
    }

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;
//    @Override
//    public void configure(ClientDetailsServiceConfigurer clientDetailsServiceConfigurer) throws Exception{
//        /**
//         * @Author:Hongwei Li
//         * @Description:
//         * @Date:14:25 2020/4/9
//         * @Param:[clientDetailsServiceConfigurer]
//         * @Return:void
//        **/
//        clientDetailsServiceConfigurer.withClientDetails(jdbcClientDeatails());
//    }

}
